package org.uca.dss.curso1011.grupo9;

import au.com.bytecode.opencsv.CSVReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.joda.time.LocalTime;

/**
 * Clase que carga de los csv los trayectos y los trenes
 * @author eldruin
 */
public class Carga {
    private Map<String,Medio> medios;
    private List<Trayecto> trayectos;

    /**
     * Constructor
     */
    public Carga()
    {
        medios = new HashMap<String,Medio>();
        trayectos = new ArrayList<Trayecto> ();
    }

    public static void init() throws Exception {
    }

    /**
     * Carga los trenes y los trayectos de los ficheros dados
     * @param archivo_CSV_trenes
     * @param archivo_CSV_trayectos
     * @return si se han cargado correctamente
     * @throws Excepciones
     */
    public boolean cargar(String archivo_CSV_trenes,
                          String archivo_CSV_trayectos) throws Excepciones
    {
        boolean resultado;
        resultado = cargarTrenes(archivo_CSV_trenes);
        resultado &= cargarTrayectos(archivo_CSV_trayectos);

        return resultado;
    }

    /**
     * Carga los trenes
     * @param fileNameCSV
     * @return si se han cargado bien
     * @throws Excepciones
     */
    private boolean cargarTrenes(String fileNameCSV) throws Excepciones
    {
        boolean resultado = false;
        CSVReader reader;
        try {
            reader = new CSVReader(new FileReader(fileNameCSV));

            try {
                String []nextLine;


                while ((nextLine = reader.readNext()) != null) {

//                    <nombre tren>,<asientos>,<preciotrayecto>
                        //pequeno,10, 1
                        //grande, 30, 1
                        //ave, 30, 3

                    if (nextLine.length != 3)
                        throw new Excepciones("Bad CSV format");

                    String nombreTren = nextLine[0].trim();
                    int numAsientos = Integer.parseInt(nextLine[1].trim());
                    double precioTrayecto = Double.parseDouble(nextLine[2].trim());

                    crearTren(nombreTren, numAsientos, precioTrayecto);

                    resultado = true;
                }
            } catch (IOException ex) {
                Logger.getLogger("cargarTrenes").log(Level.SEVERE, null, ex);
                throw new IllegalArgumentException(ex.getMessage());
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger("cargarTrenes").log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex.getMessage());
        }

        return resultado;
    }

    /**
     * Carga los trayectos.
     * Necesita que los trenes estén creados antes.
     * @param nombreFichero
     * @return si se han cargado bien
     * @throws Excepciones
     */
    private boolean cargarTrayectos(String nombreFichero) throws Excepciones
    {
        boolean resultado = false;
        CSVReader reader;
        try {
            reader = new CSVReader(new FileReader(nombreFichero));

            try {
                String []nextLine;
                int codigoTrayecto = 1;
                while ((nextLine = reader.readNext()) != null) {
                    // System.out.println(nextLine[0] + nextLine[1] + "etc...");
                    // por cada linea tenemos que crear un nuevo trayecto
                    // <nombre tren>,<ciudad origen>,<ciudad destino>,<tramos>,<hora salida1>,<hola llegada1>, <hora salida2>, <hora llegada2>

                    if (nextLine.length < 6)
                        throw new Excepciones("Bad CSV format");

                    String nombreMedio = nextLine[0].trim();
                    String ciudadOrigen = nextLine[1].trim();
                    String ciudadDestino = nextLine[2].trim();
                    int numTramos = Integer.parseInt(nextLine[3].trim());
                    LocalTime horaSalida = new LocalTime(nextLine[4].trim());
                    LocalTime horaLlegada = new LocalTime(nextLine[5].trim());//LocalTime.fromDateFields(nextLine[4]);
                    Medio medio = medios.get(nombreMedio);
                    //LocalTime.fromDateFields(nextLine[4]);
                    crearTrayecto(codigoTrayecto, medio, ciudadOrigen, ciudadDestino, numTramos, horaSalida, horaLlegada);
                    codigoTrayecto++;
                    resultado = true;
                    int i = 6;
                    while (i < nextLine.length -1)
                    {
                        LocalTime horaSalidaI = new LocalTime(nextLine[i].trim());
                        i++;
                        LocalTime horaLlegadaI = new LocalTime(nextLine[i].trim());
                        i++;
                        crearTrayecto(codigoTrayecto, medio, ciudadOrigen, ciudadDestino, numTramos, horaSalidaI, horaLlegadaI);
                        codigoTrayecto++;
                    }
                }
            } catch (IOException ex) {
                Logger.getLogger("cargarTrayectos").log(Level.SEVERE, null, ex);
                throw new IllegalArgumentException(ex.getMessage());
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger("cargarTrayectos").log(Level.SEVERE, null, ex);
            throw new RuntimeException(ex.getMessage());
        }

        return resultado;
    }

    /**
     * Crerar un tren con los parámetros especificados y lo almacena
     * @param nombreTren
     * @param asientos
     * @param precio_tramo
     * @return Si se ha creado nuevo
     */
    private boolean crearTren(String nombreTren, int asientos, double precio_tramo)
    {
        boolean bCreado = false;
        if (!medios.containsKey(nombreTren))
        {
            Tren tren = new Tren(nombreTren, asientos, precio_tramo);
            medios.put(nombreTren, tren);
            bCreado = true;
        }

        return bCreado;
    }

    /**
     * Crea un trayecto con los parámetros especificados y lo almacena
     * @param codigoTrayecto
     * @param medio
     * @param ciudadOrigen
     * @param ciudadDestino
     * @param numeroTramos
     * @param horaSalida
     * @param horaLlegada
     */
    private void crearTrayecto(int codigoTrayecto, Medio medio, String ciudadOrigen,
                               String ciudadDestino, int numeroTramos,
                               LocalTime horaSalida, LocalTime horaLlegada)
    {
        Trayecto trayecto =
                new Trayecto(codigoTrayecto, medio,
                             ciudadOrigen, ciudadDestino, numeroTramos,
                             horaSalida, horaLlegada);
        trayectos.add(trayecto);
    }

    /**
     * @return lista de trayectos
     */
    public List<Trayecto> getTrayectos() {
        return trayectos;
    }
}
